home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / w00w00 / sectools / SRS / client / src / spool.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-12  |  13.5 KB  |  601 lines

  1. #include "headers.h"
  2.  
  3. int streamfd;
  4.  
  5. /* initialize spooling files */
  6. void initSpool()
  7. {
  8. #  if !defined(SUN) && !defined(BSD)
  9.    int res;
  10. #  endif
  11.  
  12.    char spoolfile[MAXFNAMESIZE];
  13.    memset(spoolfile, 0, sizeof(spoolfile));
  14.  
  15.    if (spoolFile == NULL)
  16.       (void)sprintf(spoolfile, "%s/spool/%s", SRSdir, LOGFILE);
  17.  
  18.    else 
  19.       (void)snprintf(spoolfile, sizeof(spoolFile)-1, "%s", spoolFile);
  20.  
  21.    if (spoolfd != NULL) (void)fclose(spoolfd);
  22.  
  23. # if !defined(SUN) && !defined(BSD)
  24. #  ifdef _POSIX_SAVED_IDS
  25.    res = setuid(0);
  26. #  else
  27.    res = seteuid(0);
  28. #  endif
  29.  
  30.    if (res == ERROR)
  31.    {
  32.       error("error setting [e]uid: %s\n\n", strerror(errno));
  33.       quit(ERROR);
  34.    }
  35. # endif
  36.  
  37.    spoolfd = fopen(spoolfile, "a+b");
  38.    if (spoolfd == NULL)
  39.    {
  40.       error("(in spool child) error opening %s: %s\n\n", spoolfile,
  41.             strerror(errno));
  42.  
  43.       quit(ERROR);
  44.    }
  45.  
  46.    (void)chmod(spoolfile, S_IREAD | S_IWRITE);
  47.  
  48. # if !defined(SUN) && !defined(BSD)
  49.    if (pwd != NULL)
  50.    {
  51. #     ifdef _POSIX_SAVED_IDS
  52.       res = setuid(pwd->pw_uid);
  53. #     else
  54.       res = seteuid(pwd->pw_uid);
  55. #     endif
  56.  
  57.       if (res == ERROR)
  58.       {
  59.          error("error setting [e]uid: %s\n\n", strerror(errno));
  60.          quit(ERROR);
  61.       }
  62.    }
  63. # endif
  64. }
  65.  
  66.  
  67. /* ---------------------------- */
  68.  
  69.  
  70. /* spool system logs to spool file locally */
  71. void doSpooling()
  72. {
  73.    int res;
  74.  
  75. #  if !defined(BSD) && !defined(SUN)
  76.    int fd;
  77. #  endif
  78.  
  79. #  ifndef SUN
  80.    int count = 0;
  81. #  endif
  82.  
  83. #  ifndef SUN
  84.    char newmsg[MAXLOGSIZE];
  85.    char logmsg[MAXLOGSIZE];
  86. #  endif
  87.  
  88.    char readbuf[MAXREADSIZE];   
  89.  
  90. #  ifndef SUN
  91.    char *logptr, *dataptr, *newptr;
  92. #  endif
  93.  
  94. #  ifdef BSD
  95.    u_char cmsg[MAXREADSIZE/4];
  96.  
  97.    struct iovec iov;
  98.    struct msghdr msghdr;
  99.  
  100. #  elif SUN
  101.    char *bufptr;
  102.    int flags = 0;
  103. #  endif
  104.  
  105.    FD_ZERO(&readfds);
  106.    errno = 0, spooling = 1;
  107.  
  108.    debug("awaiting system logs to spool...\n\n");
  109.  
  110. #  ifdef BSD
  111.    iov.iov_base = readbuf;
  112.    iov.iov_len = sizeof(readbuf)-1;
  113. #  endif
  114.  
  115.    while(1)
  116.    {
  117. #     ifdef SUN
  118.       struct log_ctl hdr;
  119.       struct strbuf ctl, dat;
  120. #     endif
  121.  
  122.       memset(readbuf, 0, sizeof(readbuf));
  123.  
  124. #     if !defined(SUN) && !defined(BSD)
  125.       for (nfds = 0; nfds < FD_SETSIZE-2; nfds++)
  126.          if (FD_ISSET(nfds, &unixm)) FD_SET(nfds, &readfds);
  127. #     endif
  128.  
  129.       FD_SET(funix, &readfds);
  130.       if (klogfd > 0) FD_SET(klogfd, &readfds);
  131.  
  132.       nfds = 0, errno = 0;
  133.       nfds = select(FD_SETSIZE, (fd_set *) &readfds, (fd_set *) NULL,
  134.                     (fd_set *) NULL, (struct timeval *) NULL);
  135.  
  136.       /* won't happen.. we don't have a timeout */
  137.       if (nfds == 0)
  138.       {
  139.          error("(in spool child) no new data/activity... "
  140.                "timed out in select()\n\n");
  141.  
  142.          FD_CLR(funix, &readfds);
  143.          if (klogfd > 0) FD_CLR(klogfd, &readfds);
  144.  
  145.          continue;
  146.       }
  147.     
  148.       else if (nfds == ERROR)
  149.       {
  150.          if (errno == EINTR) continue;
  151.  
  152.          error("(in spool child) error with select(): %s\n\n",
  153.                strerror(errno));
  154.  
  155.          quit(ERROR);
  156.       }
  157.  
  158.       /* ------------------------------- */
  159.  
  160.       if ((klogfd > 0) && (FD_ISSET(klogfd, &readfds)))
  161.       {
  162.          memset(readbuf, 0, sizeof(readbuf));
  163.  
  164.          res = read(klogfd, readbuf, sizeof(readbuf)-1);
  165.          if (res == ERROR)
  166.          {
  167.             error("error reading klogfd.. removing\n\n");
  168.  
  169.             FD_CLR(klogfd, &readfds);
  170.             (void)close(klogfd), klogfd = ERROR;
  171.          }
  172.  
  173.          else if (((readbuf[0] != '\0') && (readbuf[0] != '\n')) &&
  174.                   (isprint((int)readbuf[1]) != 0))
  175.          {
  176.             /* FIX - do it (add the kern def pri.. "kernel: " and */
  177.             /*     - doLogging it.. then sending it to server     */
  178.  
  179.             debug("new klog msg = %s\n", readbuf);
  180.          }
  181.  
  182.          FD_CLR(klogfd, &readfds);
  183.       }
  184.  
  185.       /* ------------------------------- */
  186.  
  187. #     if !defined(SUN) && !defined(BSD)
  188.       for (fd = 0; fd < FD_SETSIZE; fd++)
  189.          if ((FD_ISSET(fd, &readfds)) && (FD_ISSET(fd, &unixm)))
  190.  
  191. #     else
  192.       if (FD_ISSET(funix, &readfds))
  193. #     endif
  194.  
  195.       {
  196.          memset(readbuf, 0, sizeof(readbuf));
  197.  
  198. #        ifdef BSD
  199.          memset(cmsg, 0, sizeof(cmsg));
  200.          memset(&msghdr, 0, sizeof(msghdr));
  201.  
  202.          msghdr.msg_iov = &iov;
  203.          msghdr.msg_iovlen = 1;
  204.          msghdr.msg_flags = 0;
  205.          msghdr.msg_control = (caddr_t)cmsg;
  206.          msghdr.msg_controllen = sizeof(cmsg);
  207.  
  208.          /* FIX - do something with credentials.. */
  209.  
  210.          res = recvmsg(funix, &msghdr, 0);
  211.          if (res == ERROR)
  212.          {
  213.             error("error with recvmsg from %s: %s\n\n", SYSLOGFILE,
  214.                   strerror(errno));
  215.  
  216.             quit(ERROR);
  217.          }
  218.  
  219. #        elif SUN
  220.          dat.buf = readbuf;
  221.          dat.maxlen = sizeof(readbuf) - 1;
  222.  
  223.          ctl.buf = (caddr_t)&hdr;
  224.          ctl.maxlen = sizeof(struct log_ctl);
  225.  
  226.          while(1)
  227.          {
  228.             errno = 0;
  229.  
  230.             res = getmsg(funix, &ctl, &dat, &flags);
  231.             if (res != MOREDATA)
  232.                if ((res != ERROR) || ((res == ERROR) && (errno != EINTR)))
  233.                   break;
  234.  
  235.             bufptr = &dat.buf[dat.len], *bufptr = '\0';
  236.             while ((*bufptr != '\n') && (bufptr != readbuf)) bufptr -= 1;
  237.  
  238.             /* FIX - on all these STREAM's we gotta send pri prolly */
  239.  
  240.             if (bufptr != readbuf) *bufptr = '\0';
  241.  
  242.             if (((readbuf[0] != '\0') && (readbuf[0] != '\n')) &&
  243.                 (isprint((int)readbuf[1]) != 0))
  244.             {
  245.                send_data("STREAM : %s%c", readbuf,
  246.                          (readbuf[strlen(readbuf)-1] != '\n' ? '\n' : '\0'));
  247.  
  248.                doLogging(readbuf);
  249.             }
  250.  
  251.             if (readbuf != bufptr)
  252.             {
  253.                strcpy(readbuf, bufptr);
  254.                dat.maxlen = sizeof(readbuf) - strlen(readbuf) - 1;
  255.                dat.buf = &readbuf[strlen(readbuf)];
  256.             }
  257.  
  258.             else
  259.             {
  260.                dat.maxlen = sizeof(readbuf) - 1;
  261.                dat.buf = readbuf;
  262.             }
  263.          }
  264.  
  265.          if ((res == 0) && (dat.len > 0))
  266.          {
  267.             dat.buf[dat.len] = '\0';
  268.  
  269.             if (((readbuf[0] != '\0') && (readbuf[0] != '\n')) &&
  270.                 (isprint((int)readbuf[1]) != 0))
  271.             {
  272.                send_data("STREAM : %s%c", readbuf,
  273.                          (readbuf[strlen(readbuf)-1] != '\n' ? '\n' : '\0'));
  274.  
  275.                doLogging(readbuf);
  276.             }
  277.          }
  278.  
  279.          else if ((res == ERROR) && (errno != EINTR))
  280.          {
  281.             error("error in getmsg: %s\n\n", strerror(errno));
  282.  
  283.             (void)close(funix);
  284.             funix = ERROR;
  285.  
  286.             quit(ERROR);
  287.          }
  288.  
  289. #        else
  290.          while(1)
  291.          {
  292.             errno = 0;
  293.  
  294.             memset(readbuf, 0, sizeof(readbuf));
  295.             res = read(fd, readbuf, sizeof(readbuf)-1);
  296.  
  297.             if ((res <= 0) && (errno > 0))
  298.             {
  299.                if (errno == EINTR) continue;
  300.  
  301.                error("error with read(): %s\n", strerror(errno));
  302.                (void)close(fd), quit(ERROR);
  303.             }
  304.  
  305.             else break;
  306.          }
  307.  
  308.          FD_CLR(fd, &readfds);
  309.          FD_CLR(fd, &unixm);
  310. #        endif
  311.  
  312. #        ifndef SUN
  313.          if (((readbuf[0] != '\0') && (readbuf[0] != '\n')) &&
  314.              (isprint((int)readbuf[1]) != 0))
  315.          {
  316.             memset(newmsg, 0, sizeof(newmsg));
  317.             memset(logmsg, 0, sizeof(logmsg));
  318.  
  319.             write_spool("STREAM : %s%c", readbuf, 
  320.                         (readbuf[strlen(readbuf)-1] != '\n' ? '\n' : '\0'));
  321.  
  322.             doLogging(readbuf);
  323.  
  324.             logptr = logmsg;
  325.             dataptr = readbuf, dataptr += 20;
  326.  
  327.             count = 0;
  328.             while ((*dataptr) && (isprint((int)*dataptr) != 0) &&
  329.                    (count < (int)sizeof(logmsg)))
  330.             {
  331.                *logptr++ = *dataptr++;
  332.                count++;
  333.             }
  334.  
  335.             if (isprint((int)prevlogmsg[0]) == 0)
  336.             {
  337.                (void)strncpy(prevlogmsg, logmsg, sizeof(prevlogmsg)-1);
  338.                prevlogtime = time(NULL);
  339.  
  340.                doLogging(readbuf);
  341.             }
  342.  
  343.             else if (strncmp(logmsg, prevlogmsg, strlen(prevlogmsg)) == 0)
  344.             {
  345.                if ((time(NULL) - prevlogtime) >= REPTIME)
  346.                {
  347.                   char repmsg[MAXLOGSIZE - 20];
  348.  
  349.                   memset(repmsg, 0, sizeof(repmsg));
  350.  
  351.                   if (repcount == 1)
  352.                      sprintf(repmsg, " last message repeated %d time\n",
  353.                              repcount);
  354.  
  355.                   else
  356.                      sprintf(repmsg, " last message repeated %d times\n",
  357.                              repcount);
  358.  
  359.                   repcount = 0;
  360.                   prevlogtime = time(NULL);
  361.  
  362.                   count = 0;
  363.                   newptr = newmsg, dataptr = readbuf;
  364.  
  365.                   while ((*dataptr) && (isprint((int)*dataptr) != 0) &&
  366.                          (count < (int)sizeof(newmsg)) && (count < 19))
  367.                   {
  368.                      *newptr++ = *dataptr++;
  369.                      count++;
  370.                   }
  371.  
  372.                   strncat(newmsg, repmsg,
  373.                           sizeof(newmsg) - strlen(newmsg) - 1);
  374.  
  375.                   debug("newmsg = %s\n", newmsg);
  376.                   doLogging(newmsg);
  377.                }
  378.  
  379.                else
  380.                {
  381.                   repcount++;
  382.                   debug("last message repeated...\n\n");
  383.                }
  384.             }
  385.  
  386.             else
  387.             {
  388.                prevlogtime = time(NULL);
  389.                (void)strncpy(prevlogmsg, logmsg, sizeof(prevlogmsg)-1);
  390.                doLogging(readbuf);
  391.             }
  392.          }
  393. #        endif
  394.       }     
  395.  
  396. #     if !defined(SUN) && !defined(BSD)
  397.       if (FD_ISSET(funix, &readfds))
  398.       {
  399.          /* accept a new connection */
  400.          /* debug("got new unix connect\n"); */
  401.  
  402.          fd = accept(funix, (struct sockaddr *)NULL, 0);
  403.          if (fd >= 0)
  404.          {
  405.             FD_SET(fd, &unixm);
  406.             FD_SET(fd, &readfds);
  407.          }
  408.  
  409.          else error("error with accept(): %s\n", strerror(errno));
  410.       }
  411. #     endif
  412.  
  413.    }
  414. }
  415.  
  416.  
  417. /* ---------------------------- */
  418.  
  419.  
  420. /* write data to spool file */
  421. void write_spool(char *fmt, ...)
  422. {
  423.    int res;
  424.  
  425.    va_list args;
  426.    char writebuf[MAXWRITESIZE];
  427.    
  428.    memset(writebuf, 0, sizeof(writebuf));
  429.    
  430.    va_start(args, fmt);
  431.    (void)vsnprintf(writebuf, sizeof(writebuf)-1, fmt, args);
  432.    va_end(args);
  433.    
  434.    writebuf[sizeof(writebuf)-1] = '\0'; /* NULL terminate the string */
  435.    
  436.    debug("(in write_spool) logging %s%c", writebuf,
  437.          (strstr(writebuf, "\n\n") == NULL ? '\n' : '\0'));
  438.    
  439.    while(1)
  440.    {
  441.       res = fputs(writebuf, spoolfd);
  442.  
  443.       if (strchr(writebuf, '\n') != NULL)
  444.          if (logs[curlogfd].nsync != 1) (void)fflush(spoolfd);
  445.  
  446.       if (res == ERROR)
  447.       {
  448.          if (errno == EINTR) continue;
  449.  
  450.          error("(in spool child) error writing to %s/spool/%s: %s\n\n", 
  451.                SRSdir, LOGFILE, strerror(errno));
  452.  
  453.          quit(ERROR);
  454.       }
  455.  
  456.       else break;
  457.    }
  458.  
  459.    if (strchr(writebuf, '\n') == NULL) 
  460.       if (logs[curlogfd].nsync != 1)
  461.          (void)fflush(spoolfd);
  462.  
  463.    while(1)
  464.    {
  465.       res = fprintf(spoolfd, "%s", writebuf);
  466.  
  467.       if (strchr(writebuf, '\n') == NULL) 
  468.          if (logs[curlogfd].nsync != 1)
  469.             (void)fflush(spoolfd);
  470.  
  471.       if (res == ERROR)
  472.       {
  473.          if (errno == EINTR) continue;
  474.  
  475.          error("(in spool child) error writing to %s/spool/%s: %s\n\n", 
  476.                SRSdir, LOGFILE, strerror(errno));
  477.  
  478.          quit(ERROR);
  479.       }
  480.  
  481.       else break;
  482.    }
  483.  
  484.    if (strchr(writebuf, '\n') == NULL) 
  485.       if (logs[curlogfd].nsync != 1)
  486.          (void)fflush(spoolfd);
  487. }
  488.  
  489.  
  490. /* ---------------------------- */
  491.  
  492.  
  493. /* kill the spooling process */
  494. void killSpooler()
  495. {
  496.    int res;
  497.  
  498.    if (spooling != 1) return;
  499.  
  500.    debug("(in spool parent) now killing spooling process\n");
  501.  
  502. # if !defined(SUN) && !defined(BSD)
  503. #  ifdef _POSIX_SAVED_IDS
  504.    res = setuid(0);
  505. #  else
  506.    res = seteuid(0);
  507. #  endif
  508.  
  509.    if (res == ERROR)
  510.    {
  511.       error("error setting [e]uid: %s\n\n", strerror(errno));
  512.       quit(ERROR);
  513.    }
  514. # endif
  515.  
  516.    res = kill(spoolpid, SIGTERM);
  517.    if (res == ERROR)
  518.    {
  519.       error("(in spool parent)\n"
  520.             "error killing spooling process (pid %d): %s\n",
  521.             spoolpid, strerror(errno));
  522.    }
  523.  
  524. # if !defined(SUN) && !defined(BSD)
  525.    if (pwd != NULL)
  526.    {
  527. #     ifdef _POSIX_SAVED_IDS
  528.       res = setuid(pwd->pw_uid);
  529. #     else
  530.       res = seteuid(pwd->pw_uid);
  531. #     endif
  532.  
  533.       if (res == ERROR)
  534.       {
  535.          error("error setting [e]uid: %s\n\n", strerror(errno));
  536.          quit(ERROR);
  537.       }
  538.    }
  539. # endif
  540.  
  541.    spoolpid = ERROR;
  542.    spooling = 0, didspool = 1;
  543.    debug("(in spool parent) spooling now is being turned off\n");
  544. }
  545.  
  546.  
  547. /* ----------------------------- */
  548.  
  549.  
  550. /* fork a child to spool */
  551. void forkSpool()
  552. {
  553.    int res;
  554.  
  555.    spooling = 1;
  556.  
  557.    res = fork();
  558.    if (res == ERROR)
  559.    {
  560.       error("error forking child to spool locally: %s\n\n",
  561.             strerror(errno));
  562.  
  563.       quit(ERROR);
  564.    }
  565.  
  566.    else if (res == 0)
  567.    {
  568.       (void)signal(SIGCHLD, SIG_IGN);
  569.  
  570.       spoolpid = getpid();
  571.  
  572.       /* initSpool() already done by initStream() */
  573.       /* initSpool(), */ doSpooling();
  574.    }
  575.  
  576.    else
  577.    {
  578.       spoolpid = res;
  579.  
  580.       if (gotInfoServ == 1)
  581.       {
  582.          debug("(in parent)\nnow restarting/reconnecting "
  583.                "at the top of the server list\n\n");
  584.  
  585.          curServ = 0;
  586.  
  587.          /* wait MAXTIMEOUT * 3 before giving up and getting new list */
  588.          signal(SIGALRM, restart);
  589.          alarm(MAXTIMEOUT * 3); 
  590.       }
  591.  
  592.       else
  593.       {
  594.          debug("(in parent) now attempting to reconnect to info servers\n"); 
  595.  
  596.          if (done == 1) return;
  597.          else longjmp(infoconn, 1);
  598.       }
  599.    }
  600. }
  601.